﻿// 170. 加成序列  jinjiezhinan.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <unordered_set>
#include <memory.h>
using namespace std;

/*
https://www.acwing.com/problem/content/172/

满足如下条件的序列 X（序列中元素被标号为 1、2、3…m）被称为“加成序列”：

X[1]=1
X[m]=n
X[1]<X[2]<…<X[m−1]<X[m]
对于每个 k（2≤k≤m）都存在两个整数 i 和 j （1≤i,j≤k−1，i 和 j 可相等），使得 X[k]=X[i]+X[j]。
你的任务是：给定一个整数 n，找出符合上述条件的长度 m 最小的“加成序列”。

如果有多个满足要求的答案，只需要找出任意一个可行解。

输入格式
输入包含多组测试用例。

每组测试用例占据一行，包含一个整数 n。

当输入为单行的 0 时，表示输入结束。

输出格式
对于每个测试用例，输出一个满足需求的整数序列，数字之间用空格隔开。

每个输出占一行。

数据范围
1≤n≤100
输入样例：
5
7
12
15
77
0
输出样例：
1 2 4 5
1 2 4 6 7
1 2 4 8 12
1 2 4 5 10 15
1 2 4 8 9 17 34 68 77
*/


const int N = 110;
int n; int k;
int minLen = 0;
int path[N];
void printPath(int x) {
	for (int i = 0; i < x; i++) {
		cout << path[i] << " ";
	}
	cout << endl;
}

bool dfs(int idx) {
	if (idx-1 == k) return path[k] == n;
	if (path[idx-1] > n) return false;

	int st[200]; memset(st, 0, sizeof st);
	for (int i = idx-1; i >= 0; i--) {
		for (int j = i; j >= 0; j--) {
			int  sum = path[i] + path[j];
			if (sum > n) { continue; }
			if (st[sum]==1) { continue; }
			if (sum <= path[idx - 1]) { continue; }
			minLen = idx + 1;
			path[idx] = sum;
			if (dfs(idx + 1)) return true;
			st[sum] = 1;
			path[idx] = 0;
			minLen = idx;
		}
	}

	return false;
}

int main()
{
	path[0] = 1; path[1] = 2;
	while (cin >> n, n) {
		if (n <= 2) { printPath(n); continue; }
		k = 1;
		while (!dfs(2)) k++;
		printPath(minLen);
	}

	return 0;
}

 